/**
 * 函数， 就是将一些复用的功能模块封装成的一块儿
 *
 * */

/**
 * 方法一： 使用new 类 对象的形式
 * @type {Function}
 */
// 使用new 类来实现函数的定义
const newFunc = new Function('title', 'console.log(title)')
newFunc('ck')


/**
 * 使用字面量格式
 * @param a
 * @param b
 * @returns {*}
 */
// 使用字面量格式
function add(a, b) {
    return a + b
}

// 使用函数名直接调用
add(1, 2)


/**
 * 用对象的属性来定义
 * @type {{name: null, show(): null}}
 */
let User = {
    name: null,
    show() {
        console.log(this.name)
        return this.name
    }
}
User.name = 'hahah'
User.show()


/**
 * 立即执行， 在函数进入的时候， 就直接执行了
 * 匿名函数， 可以携带参数
 */

for (var i = 0; i < 10; i++) {
    // (function (num) {
    //     setTimeout(() => {
    //         console.log(num)
    //     }, 2000)
    // })(i)
}

for (var i = 0; i < 10; i++) {
    // setTimeout(()=> {
    //     console.log(i)
    // })
}

/**
 * 函数提升， function 可以被提到最上面
 * 即使在被定义的上面调用， 也不会进行报错
 */

ck()

function ck() {
    // 这里打印的是ck的类型和名称， 不是字符串 'ck'
    console.log(ck)
}

/**
 * 形参、实参
 */

function ckV1(num1, num2) {
    console.log(num1 + num2)
    return num1 + num2
}

ckV1(1) // NaN not a number
console.log(10 + undefined)
console.log(10 + null)
console.log(10 + true)
console.log(10 + false)


/**
 * 默认参数, arguments 是一个类数组， 但是不是数组，
 * 可以使用Array.from()转换成真正的数组，
 * */

function ckV2(num1, num2){
    const args =  Array.from(arguments)
    if(Array.isArray(args)){
        for (let i = 0; i < args.length; i++) {
            if(typeof args[i] === 'object'){
                for (const argsKey in args[i]) {
                    console.log(args[i][argsKey])
                }
            }else {
                console.log(args[i])
            }
        }
    }
}
ckV2(1, 2, 100, [100], 90, 'str', 'name', true, {name: 'ck', age:10})

function ckV5(num1, num2, ...rest){
    // 这里获取的就是除去形参之外的其他参数.
    const args =  Array.from(rest)
    if(Array.isArray(args)){
        for (let i = 0; i < args.length; i++) {
            if(typeof args[i] === 'object'){
                for (const argsKey in args[i]) {
                    console.log(args[i][argsKey])
                }
            }else {
                console.log(args[i])
            }
        }
    }
}
ckV5(1, 2, 100, [100], 90, 'str', 'name', true, {name: 'ck', age:10})

// 如果没有year, 那么year给一个1年的默认值。
function ckV3(total, year) {
    year  = year || 1
    console.log(total / year)
    return total / year
}


ckV3(190)
ckV3(190, 3)


//  这里在函数定义的时候， 如果year没有值， 就使用1
function ckV4(total, year=1) {
    console.log(total / year)
    return total / year
}
ckV4(190, 3)


/**
 * 递归调用
 */

function fabractor(num = 3) {
    return num ===1 ? num : num += fabractor(--num)
}

console.log(fabractor());


function sum(...args){
    return args.length === 0 ? 0: args.pop() + sum(...args)
}

console.log(sum(3));


/**
 * this 代表当前的对象
 */

const name = 'ck'
let T = {
    name:'bob',
    show(){
        console.log(this.name)
    },
    getName() {
        console.log(name)
    }
}

T.show()  // 带了this，获取到的是T对象里面的bob
T.getName() // 没有带this， 获取的是全局变量里面的 ck


/**
 * 求两个数组中不相同的数据
 */

function unique() {
    const a = [1, 3, 4, 56,9, 10]
    const b = [4, 3, 19, 80, 70, 10]

}

